using System.Linq.Expressions;
using AdmissionQA.Domain.Entities;
using AdmissionQA.Domain.Repositorys;
using AdmissionQA.Infrastructure.Date;
using Microsoft.EntityFrameworkCore;

namespace AdmissionQA.Infrastructure.Repositorys;

/// <summary>
/// Entity Framework 通用仓储实现类
/// 提供基础的CRUD操作，支持软删除
/// </summary>
/// <typeparam name="T">实体类型，必须继承自EntityBase</typeparam>
public class EFRepository<T>(AdmissionQADbContext db) : IRepository<T>
    where T : EntityBase
{
    private readonly AdmissionQADbContext _db = db;
    private readonly DbSet<T> _tb = db.Set<T>();

    /// <summary>
    /// 创建新实体
    /// </summary>
    /// <param name="entity">要创建的实体</param>
    /// <returns>异步任务</returns>
    public async Task CreateAsync(T entity)
    {
        await _tb.AddAsync(entity);
        await _db.SaveChangesAsync();
    }

    /// <summary>
    /// 批量创建实体
    /// </summary>
    /// <param name="entities">要创建的实体集合</param>
    /// <returns>异步任务</returns>
    public async Task CreateRangeAsync(IEnumerable<T> entities)
    {
        await _tb.AddRangeAsync(entities);
        await _db.SaveChangesAsync();
    }

    /// <summary>
    /// 根据ID获取实体（排除已删除的实体）
    /// </summary>
    /// <param name="id">实体ID</param>
    /// <returns>找到的实体，如果不存在则返回null</returns>
    public async Task<T?> GetByIdAsync(Guid id)
    {
        return await _tb.Where(item => !item.IsDeleted).FirstOrDefaultAsync(item => item.Id == id);
    }

    /// <summary>
    /// 根据条件获取实体列表（排除已删除的实体）
    /// </summary>
    /// <param name="condition">查询条件表达式</param>
    /// <returns>符合条件的实体列表</returns>
    public async Task<IEnumerable<T>> GetListConditionAsync(Expression<Func<T, bool>> condition)
    {
        return await _tb.Where(item => !item.IsDeleted).Where(condition).ToListAsync();
    }

    /// <summary>
    /// 根据条件获取单个实体（排除已删除的实体）
    /// </summary>
    /// <param name="condition">查询条件表达式</param>
    /// <returns>找到的实体，如果不存在则返回null</returns>
    public async Task<T?> GetOneConditionAsync(Expression<Func<T, bool>> condition)
    {
        return await _tb.Where(item => !item.IsDeleted).FirstOrDefaultAsync(condition);
    }

    /// <summary>
    /// 分页获取实体列表（排除已删除的实体）
    /// </summary>
    /// <param name="pageIndex">页码，从0开始</param>
    /// <param name="pageSize">每页大小</param>
    /// <returns>分页后的实体列表</returns>
    public async Task<IEnumerable<T>> GetPagedAsync(int pageIndex = 0, int pageSize = 10)
    {
        return await _tb.Where(item => !item.IsDeleted)
            .OrderBy(item => item.CreatedAt)
            .Skip(pageIndex * pageSize)
            .Take(pageSize)
            .ToListAsync();
    }

    /// <summary>
    /// 获取所有实体（排除已删除的实体）
    /// </summary>
    /// <returns>所有未删除的实体列表</returns>
    public async Task<IEnumerable<T>> GetAllAsync()
    {
        return await _tb.Where(item => !item.IsDeleted).ToListAsync();
    }

    /// <summary>
    /// 获取实体总数（排除已删除的实体）
    /// </summary>
    /// <returns>实体总数</returns>
    public async Task<int> GetCountAsync()
    {
        return await _tb.Where(item => !item.IsDeleted).CountAsync();
    }

    /// <summary>
    /// 根据条件获取实体数量（排除已删除的实体）
    /// </summary>
    /// <param name="condition">查询条件表达式</param>
    /// <returns>符合条件的实体数量</returns>
    public async Task<int> GetCountAsync(Expression<Func<T, bool>> condition)
    {
        return await _tb.Where(item => !item.IsDeleted).Where(condition).CountAsync();
    }

    /// <summary>
    /// 更新实体
    /// </summary>
    /// <param name="entity">要更新的实体</param>
    /// <returns>异步任务</returns>
    public async Task UpdateAsync(T entity)
    {
        entity.UpdatedAt = DateTime.UtcNow;
        _tb.Update(entity);
        await _db.SaveChangesAsync();
    }

    /// <summary>
    /// 批量更新实体
    /// </summary>
    /// <param name="entities">要更新的实体集合</param>
    /// <returns>异步任务</returns>
    public async Task UpdateRangeAsync(IEnumerable<T> entities)
    {
        entities.ToList().ForEach(item => item.UpdatedAt = DateTime.UtcNow);
        _tb.UpdateRange(entities);
        await _db.SaveChangesAsync();
    }
}
